home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Beta / Quicktime 2.0 Beta.iso / Programming Stuff / Sample Code / TimeCode Samples / AddTimeCodeƒ / AddTC.c next >
Encoding:
C/C++ Source or Header  |  1994-05-12  |  13.5 KB  |  539 lines  |  [TEXT/KAHL]

  1. #include <errors.h>
  2. #include <memory.h>
  3. #include <qdoffscreen.h>
  4. #include <palettes.h>
  5. #include <resources.h>
  6. #include <toolutils.h>
  7. #include <osutils.h>
  8. #include <files.h>
  9. #include <desk.h>
  10. #include <events.h>
  11. #include <osevents.h>
  12. #include <menus.h>
  13. #include <timer.h>
  14. #include <gestaltequ.h>
  15. #include <string.h>
  16. #include <strings.h>
  17. #include <fonts.h>
  18. #include <dialogs.h>
  19. #include <BDC.h>
  20. #include <QuickDrawText.h>
  21.  
  22. #include <stdio.h>
  23. #include <pascal.h>
  24.  
  25. #include <Components.h>
  26. #include <Movies.h>
  27. #include <QuickTimeComponents.h>
  28.  
  29. Str255 tcSrcName;
  30. Boolean tcDisplayTimeCode = false;
  31. Boolean tcDisplayBelowVideo = true;
  32. TimeScale tcTimeScale = 2997;
  33. TimeValue tcFrameDur = 100;
  34. long tcNumFrames = 30;
  35. Boolean tcDropFrameVal = true;
  36. Boolean tc24Hour = true;
  37. Boolean tcNegOK = false;
  38. Boolean tcIsNeg = false;
  39. long tcHours = 0;
  40. long tcMinutes = 0;
  41. long tcSeconds = 0;
  42. long tcFrames = 0;
  43. long tcCounterVal = 0;
  44. Boolean tcUseTimeCode = true;
  45.  
  46.  
  47. extern OSErr    GetMovie(Movie *theOutMovie, short *refnum, short *resid);
  48. extern OSErr    InitEveryBody(void);
  49. extern void        main(void);
  50. extern void        AddTimeCode(Movie theMovie);
  51. extern void        DeleteTimeCodes(Movie theMovie);
  52. extern Boolean    GetTimeCodeOptions(void);
  53. extern void        setDialogTextNumber(DialogPtr d, short itemNumber, long number);
  54. extern void        setDialogTextString(DialogPtr d, short itemNumber, StringPtr str);
  55. extern Boolean    validateDialogLong(DialogPtr d, short itemNumber, long *result);
  56. ControlHandle getDItemHandle(DialogPtr d, short itemNumber);
  57. ControlHandle getDItemRect(DialogPtr d, short itemNumber, Rect *r);
  58.  
  59.  
  60. OSErr GetMovie(Movie *theOutMovie, short *refnum, short *resid)
  61. {
  62.     SFTypeList    typeList;
  63.     StandardFileReply reply;
  64.     OSErr        result = noErr;
  65.     Movie        theMovie = nil;
  66.     
  67.     typeList[0] = 'MooV';
  68.     StandardGetFile(nil, 1, typeList, &reply);
  69.     if (!reply.sfGood) goto bail;
  70.  
  71.     if (result = OpenMovieFile(&reply.sfFile, refnum, 0)) goto bail;
  72.     *resid = 0;
  73.     if (result = NewMovieFromFile(&theMovie,*refnum, resid, nil,0, nil)) goto bail;
  74.  
  75. bail:
  76.     if (result) {
  77.         DisposeMovie(theMovie);
  78.         if (*refnum) CloseMovieFile(*refnum);
  79.         *theOutMovie = nil;
  80.         }
  81.     else
  82.         *theOutMovie = theMovie;
  83.     return result;
  84. }
  85.  
  86.  
  87. OSErr InitEveryBody(void)
  88. {
  89.     InitGraf(&qd.thePort);
  90.     InitFonts();
  91.     FlushEvents(0xffff,0);
  92.     InitWindows();
  93.     InitMenus();
  94.     InitDialogs(0);
  95.     TEInit();
  96.     InitCursor();
  97.  
  98.  
  99.     return EnterMovies();
  100. }
  101.  
  102.  
  103. void main( void )
  104. {
  105.     OSErr err;
  106.     Movie theMovie;
  107.     short movieResRef;
  108.     short movieResID;
  109.     
  110.     MaxApplZone();
  111.     MoreMasters();
  112.     MoreMasters();
  113.  
  114.     err = InitEveryBody();
  115.     if (err) return;
  116.     
  117.     err = GetMovie(&theMovie, &movieResRef, &movieResID );
  118.     
  119.     if (!GetTimeCodeOptions())
  120.         return;
  121.     
  122.     // delete any existing TimeCode tracks
  123.     DeleteTimeCodes( theMovie );
  124.     AddTimeCode( theMovie );    
  125.  
  126.     UpdateMovieResource( theMovie, movieResRef, movieResID, nil );
  127.     CloseMovieFile( movieResRef );
  128.  
  129. }
  130.  
  131.  
  132. #ifndef fieldOffset
  133.     #define fieldOffset(type, field) ((short) &((type *) 0)->field)
  134. #endif
  135.  
  136. void DeleteTimeCodes( Movie theMovie )
  137. {
  138.     Track theTrack;
  139.     
  140.     theTrack = GetMovieIndTrackType(theMovie, 1, TimeCodeMediaType, movieTrackMediaType);
  141.     while (theTrack) {
  142.         DisposeMovieTrack( theTrack );
  143.         theTrack = GetMovieIndTrackType(theMovie, 1, TimeCodeMediaType, movieTrackMediaType);
  144.         }
  145.  
  146. }
  147.  
  148. void AddTimeCode( Movie theMovie )
  149. {
  150.     OSErr err;
  151.     OSType mediaType;
  152.     long trackCnt;
  153.     Track theTrack;
  154.     Media theMedia;
  155.     MediaHandler mh;
  156.     TimeValue editStart;
  157.     TimeValue editDur;
  158.     TimeValue mediaTime;
  159.     long i;
  160.     TimeCodeDef tcdef;
  161.     TimeCodeRecord tcrec;
  162.     UserData srcRef;
  163.     Str63 tcStr;
  164.     TimeValue movieDur;
  165.     TimeScale movieTimeScale;
  166.     TimeScale mediaTimeScale;
  167.     Rect curMovieBox;
  168.     MatrixRecord mr;
  169.     Fixed fwidth;
  170.     Fixed fheight;
  171.     long startingTrackCount;
  172.     long flags;
  173.     
  174.     // calculate track height based on text
  175.     
  176.     TCTextOptions textOptions;
  177.     FontInfo fontInfo;
  178.     
  179.     startingTrackCount = GetMovieTrackCount( theMovie );
  180.     
  181.     GetMovieBox( theMovie, &curMovieBox );
  182.     OffsetRect( &curMovieBox, -curMovieBox.left, -curMovieBox.top );
  183.     
  184.     theTrack = NewMovieTrack( theMovie, 20, 20, 0);        // random track height
  185.     theMedia = NewTrackMedia( theTrack, TimeCodeMediaType, GetMovieTimeScale(theMovie), nil, 0 );
  186.     mh = GetMediaHandler( theMedia );
  187.     
  188.     // get display options to calc box height
  189.     TCGetDisplayOptions( mh, &textOptions );
  190.     
  191.     if (!tcUseTimeCode) {
  192.         flags = tcCounter;
  193.         }
  194.     else {
  195.         flags = 0;
  196.         if (tcDropFrameVal) flags |= tcDropFrame;
  197.         if (tcIsNeg) flags |= tcNegTimesOK;
  198.         if (tc24Hour) flags |= tc24HourMax;
  199.         }
  200.     tcdef.flags = flags;
  201.     tcdef.fTimeScale = tcTimeScale;
  202.     tcdef.frameDuration = tcFrameDur;
  203.     tcdef.numFrames = tcNumFrames;
  204.  
  205.     if (!tcUseTimeCode) {
  206.         tcrec.c.counter = tcCounterVal;
  207.         }
  208.     else {
  209.         tcrec.t.hours = tcHours;
  210.         tcrec.t.minutes = tcMinutes;        // negative flag is here
  211.         tcrec.t.seconds = tcSeconds;
  212.         tcrec.t.frames = tcFrames;
  213.         if (tcIsNeg) tcrec.t.minutes |= tctNegFlag;
  214.         }
  215.  
  216.     // use starting time to figure out dimensions of track
  217.     
  218.     err = TCTimeCodeToString( mh, &tcdef, &tcrec, tcStr);
  219.     TextFont( textOptions.txFont );
  220.     TextFace( textOptions.txFace );
  221.     TextSize( textOptions.txSize );
  222.     GetFontInfo(&fontInfo);
  223.     
  224.     fheight = (long)(fontInfo.ascent + fontInfo.descent + 2)<<16;
  225.     fwidth = (long)(StringWidth(tcStr) + 4)<<16;
  226.     
  227.     GetTrackMatrix( theTrack, &mr );
  228.     if (tcDisplayBelowVideo) {
  229.         fwidth = (long)(curMovieBox.right - curMovieBox.left) << 16;
  230.         SetTrackDimensions( theTrack, fwidth, fheight );
  231.         TranslateMatrix( &mr, 0, ((long)curMovieBox.bottom) << 16 );
  232.         }
  233.     else {
  234.         SetTrackDimensions( theTrack, fwidth, fheight );
  235.         TranslateMatrix( &mr, (Fixed)(curMovieBox.left + ((curMovieBox.right - curMovieBox.left - (fwidth>>16))>>1))<<16, 
  236.                 (Fixed)(curMovieBox.bottom - (((fheight + (fheight>>1)) >> 16))) << 16 );
  237.         }
  238.     SetTrackMatrix( theTrack, &mr );
  239.     
  240.     SetTrackEnabled( theTrack, tcDisplayTimeCode?true:false );
  241.     TCSetTimeCodeFlags( mh, tcDisplayTimeCode?tcdfShowTimeCode:0, tcdfShowTimeCode );
  242.     
  243.     err = BeginMediaEdits( theMedia );
  244.     
  245.     {
  246.     TimeCodeDescriptionHandle tcdH;
  247.     long **frameH;
  248.     long size;
  249.     Handle nameH;
  250.     
  251.     size = fieldOffset(TimeCodeDescription, srcRef);
  252.     tcdH = (TimeCodeDescriptionHandle) NewHandleClear( size );
  253.     (**tcdH).descSize = size;
  254.     (**tcdH).dataFormat = TimeCodeMediaType;
  255.     (**tcdH).timeCodeDef = tcdef;
  256.     
  257.     err = NewUserData( &srcRef );
  258.     err = PtrToHand( &tcSrcName[1], &nameH, tcSrcName[0] );
  259.     err = AddUserDataText( srcRef, nameH, 'name', 1, langEnglish );
  260.     TCSetSourceRef( mh, tcdH, srcRef );
  261.     
  262.     frameH = (long**)NewHandle( sizeof(long) );
  263.     
  264.     err = TCTimeCodeToFrameNumber( mh, 
  265.                 &(**tcdH).timeCodeDef, &tcrec, *frameH );
  266.     
  267.     movieDur = GetMovieDuration(theMovie);
  268.     // Since we created the track with the same timescale as the movie,
  269.     // we don't need to convert the duration
  270.     
  271.     err = AddMediaSample( theMedia, (Handle)frameH, 0, GetHandleSize((Handle)frameH),
  272.         movieDur,
  273.         (SampleDescriptionHandle)tcdH, 
  274.         1, 0, 0 );
  275.         
  276.     DisposeHandle( (Handle) tcdH );
  277.     DisposeHandle( (Handle) frameH );
  278.     DisposeHandle( nameH );
  279.     DisposeUserData( srcRef );
  280.     }
  281.     
  282.     err = EndMediaEdits( theMedia );    
  283.  
  284.     err = InsertMediaIntoTrack( theTrack, 0, 0, movieDur, kFix1 );
  285.     
  286.     // let's record that this is timecode for all the current tracks
  287.     for (i = 1; i <= startingTrackCount; i++) {
  288.         err = AddTrackReference(GetMovieIndTrack(theMovie, i ), theTrack, TimeCodeMediaType, nil);
  289.     }
  290. }
  291.  
  292. #define diDialog 128
  293.  
  294. #define diSrcName 4
  295. #define diDisplayTimeCode 5
  296. #define diTimeScale 7
  297. #define diFrameDur 9
  298. #define diNumFrames 11
  299.  
  300. #define diUseTC 12
  301. #define diUseCounter 13
  302.  
  303. #define diDropFrame 14
  304. #define di24Hour (diDropFrame + 1)
  305. #define diNegOK (di24Hour + 1)
  306. #define diIsNeg (diNegOK + 2)
  307. #define diHours (diIsNeg + 1)
  308. #define diMinutes (diHours + 1)
  309. #define diSeconds (diMinutes + 1)
  310. #define diFrames (diSeconds + 1)
  311.  
  312. #define diCounter 24
  313. #define diBelowVideo 25
  314.  
  315. Boolean GetTimeCodeOptions(void)
  316. {
  317.     DialogPtr optionsDialog = nil;
  318.     short itemHit = cancel;
  319.     ControlHandle curCtl;
  320.     Boolean newVal;
  321.     short i;
  322.     Rect negRect;
  323.     GrafPtr curPort;
  324.     
  325.     GetPort(&curPort);
  326.     
  327.     optionsDialog = GetNewDialog( diDialog, nil, (WindowPtr)-1L );
  328.     if (!optionsDialog) goto bail;
  329.     
  330.     SetDialogDefaultItem(optionsDialog, 1);
  331.     SetDialogCancelItem(optionsDialog, 2);
  332.  
  333.     curCtl = getDItemHandle( optionsDialog, diDisplayTimeCode );
  334.     SetCtlValue(curCtl,tcDisplayTimeCode);
  335.     curCtl = getDItemHandle( optionsDialog, diBelowVideo );
  336.     SetCtlValue(curCtl,tcDisplayBelowVideo);
  337.     curCtl = getDItemHandle( optionsDialog, diDropFrame );
  338.     SetCtlValue(curCtl,tcDropFrameVal);
  339.     curCtl = getDItemHandle( optionsDialog, di24Hour );
  340.     SetCtlValue(curCtl,tc24Hour);
  341.     curCtl = getDItemHandle( optionsDialog, diNegOK );
  342.     SetCtlValue(curCtl,tcNegOK);
  343.     curCtl = getDItemRect( optionsDialog, diIsNeg, &negRect );
  344.     SetPort(optionsDialog);
  345.     MoveTo(negRect.left+2, negRect.top+17);
  346.     FrameRect(&negRect);
  347.     TextSize(20);
  348.     if (tcIsNeg) 
  349.         DrawString("\p-");
  350.     else
  351.         DrawString("\p+");
  352.     TextSize(12);
  353.  
  354.     curCtl = getDItemHandle( optionsDialog, diUseTC );
  355.     SetCtlValue(curCtl,tcUseTimeCode?1:0);
  356.     curCtl = getDItemHandle( optionsDialog, diUseCounter );
  357.     SetCtlValue(curCtl,tcUseTimeCode?0:1);
  358.  
  359.     setDialogTextNumber(optionsDialog, diTimeScale, tcTimeScale );
  360.     setDialogTextNumber(optionsDialog, diFrameDur, tcFrameDur );
  361.     setDialogTextNumber(optionsDialog, diNumFrames, tcNumFrames );
  362.     setDialogTextNumber(optionsDialog, diHours, tcHours );
  363.     setDialogTextNumber(optionsDialog, diMinutes, tcMinutes );
  364.     setDialogTextNumber(optionsDialog, diSeconds, tcSeconds );
  365.     setDialogTextNumber(optionsDialog, diFrames, tcFrames );
  366.  
  367.     setDialogTextNumber(optionsDialog, diCounter, tcCounterVal );
  368.     
  369.     setDialogTextString(optionsDialog, diSrcName, tcSrcName);
  370.  
  371. noGood:
  372.     do {
  373.     
  374.         ModalDialog( nil, &itemHit );
  375.         switch (itemHit) {
  376.             case diDisplayTimeCode:
  377.                 curCtl = getDItemHandle( optionsDialog, diDisplayTimeCode );
  378.                 SetCtlValue(curCtl,!GetCtlValue(curCtl));
  379.                 break;
  380.             case diBelowVideo:
  381.                 curCtl = getDItemHandle( optionsDialog, diBelowVideo );
  382.                 SetCtlValue(curCtl,!GetCtlValue(curCtl));
  383.                 break;
  384.             case diDropFrame:
  385.                 curCtl = getDItemHandle( optionsDialog, diDropFrame );
  386.                 SetCtlValue(curCtl,!GetCtlValue(curCtl));
  387.                 break;
  388.             case di24Hour:
  389.                 curCtl = getDItemHandle( optionsDialog, di24Hour );
  390.                 SetCtlValue(curCtl,!GetCtlValue(curCtl));
  391.                 break;
  392.             case diNegOK:
  393.                 curCtl = getDItemHandle( optionsDialog, diNegOK );
  394.                 SetCtlValue(curCtl,!GetCtlValue(curCtl));
  395.                 break;
  396.             case diUseTC:
  397.                 curCtl = getDItemHandle( optionsDialog, diUseTC );
  398.                 SetCtlValue(curCtl,1);
  399.                 curCtl = getDItemHandle( optionsDialog, diUseCounter );
  400.                 SetCtlValue(curCtl,0);
  401.                 break;
  402.             case diUseCounter:
  403.                 curCtl = getDItemHandle( optionsDialog, diUseCounter );
  404.                 SetCtlValue(curCtl,1);
  405.                 curCtl = getDItemHandle( optionsDialog, diUseTC );
  406.                 SetCtlValue(curCtl,0);
  407.                 break;
  408.             case diIsNeg:
  409.                 tcIsNeg = !tcIsNeg;
  410.                 SetPort(optionsDialog);
  411.     MoveTo(negRect.left+2, negRect.top+17);
  412.                 FrameRect(&negRect);
  413.                 InsetRect(&negRect,1,1);
  414.                 EraseRect(&negRect);
  415.                 InsetRect(&negRect,-1,-1);
  416.                 TextSize(20);
  417.                 if (tcIsNeg) 
  418.                     DrawString("\p-");
  419.                 else
  420.                     DrawString("\p+");
  421.                 TextSize(12);
  422.                 break;
  423.             }
  424.     } while ((itemHit != ok) && (itemHit != cancel));
  425.     
  426.     if (itemHit == ok) {
  427.         curCtl = getDItemHandle(optionsDialog, diSrcName);
  428.         GetIText((Handle)curCtl, tcSrcName);
  429.     
  430.         curCtl = getDItemHandle( optionsDialog, diDisplayTimeCode );
  431.         tcDisplayTimeCode = GetCtlValue(curCtl);
  432.         curCtl = getDItemHandle( optionsDialog, diBelowVideo );
  433.         tcDisplayBelowVideo = GetCtlValue(curCtl);
  434.         curCtl = getDItemHandle( optionsDialog, diDropFrame );
  435.         tcDropFrameVal = GetCtlValue(curCtl);
  436.         curCtl = getDItemHandle( optionsDialog, di24Hour );
  437.         tc24Hour = GetCtlValue(curCtl);
  438.         curCtl = getDItemHandle( optionsDialog, diNegOK );
  439.         tcNegOK = GetCtlValue(curCtl);
  440.         curCtl = getDItemHandle( optionsDialog, diUseTC );
  441.         tcUseTimeCode = (GetCtlValue(curCtl) != 0);
  442.  
  443.         if (!validateDialogLong(optionsDialog, diTimeScale, &tcTimeScale))
  444.             goto noGood;
  445.         if (!validateDialogLong(optionsDialog, diFrameDur, &tcFrameDur))
  446.             goto noGood;
  447.         if (!validateDialogLong(optionsDialog, diNumFrames, &tcNumFrames))
  448.             goto noGood;
  449.         if (!validateDialogLong(optionsDialog, diHours, &tcHours))
  450.             goto noGood;
  451.         if (!validateDialogLong(optionsDialog, diMinutes, &tcMinutes))
  452.             goto noGood;
  453.         if (!validateDialogLong(optionsDialog, diSeconds, &tcSeconds))
  454.             goto noGood;
  455.         if (!validateDialogLong(optionsDialog, diFrames, &tcFrames))
  456.             goto noGood;
  457.         if (!validateDialogLong(optionsDialog, diCounter, &tcCounterVal))
  458.             goto noGood;
  459.         }
  460.     
  461.     DisposDialog(optionsDialog);
  462. bail:
  463.     SetPort(curPort);
  464.     return (itemHit == ok);
  465. }
  466.  
  467. void setDialogTextNumber(DialogPtr d, short itemNumber, long number)
  468. {
  469.     Str255 theText;
  470.  
  471.     NumToString(number, theText);
  472.     SetIText((Handle)getDItemHandle(d, itemNumber), theText);
  473.     SelIText(d, itemNumber, 0, 32767);
  474. }
  475.  
  476.  
  477. void setDialogTextString(DialogPtr d, short itemNumber, StringPtr str)
  478. {
  479.     SetIText((Handle)getDItemHandle(d, itemNumber), str);
  480.     SelIText(d, itemNumber, 0, 32767);
  481. }
  482.  
  483. Boolean validateDialogLong(DialogPtr d, short itemNumber, long *result)
  484. {
  485.     Str255 theText;
  486.     OSErr err;
  487.     ControlHandle ch;
  488.     Boolean digitFound;
  489.     short i;
  490.  
  491.     ch = getDItemHandle(d, itemNumber);
  492.  
  493.     GetIText((Handle)ch, theText);
  494.  
  495.     digitFound = false;
  496.     for (i = 1; i < theText[0]; i++) {
  497.         if (theText[i] >= '0' && theText[i] <= '9') 
  498.             digitFound = true;
  499.         else if (digitFound) {
  500.             theText[0] = i-1;
  501.             break;
  502.         }
  503.         else if (theText[i] != ' ') {
  504.             SelIText(d, itemNumber, 0, 32767);
  505.             SysBeep(1);
  506.             return false;
  507.         }
  508.     }
  509.  
  510.     StringToNum( theText, result );
  511.  
  512.     return true;
  513. }
  514.  
  515. ControlHandle getDItemHandle(DialogPtr d, short itemNumber)
  516. {
  517.     short kind;
  518.     ControlHandle ch;
  519.     Rect r;
  520.  
  521.     GetDItem(d, itemNumber, &kind, (Handle *)&ch, &r);
  522.  
  523.     return(ch);
  524. }
  525.  
  526. ControlHandle getDItemRect(DialogPtr d, short itemNumber, Rect *r)
  527. {
  528.     short kind;
  529.     ControlHandle ch;
  530.  
  531.     GetDItem(d, itemNumber, &kind, (Handle *)&ch, r);
  532.  
  533.     return(ch);
  534. }
  535.  
  536.  
  537.  
  538.  
  539.